package com.core.base;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.Transient;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;


@Service
public abstract class BaseService<T, ID extends Serializable> implements GetMapper<T, ID> {


    public static final int SUCCESS = 0;

    public static final int ERROR = 1;


//    private SecurityContextHolder securityContextHolder = new SecurityContextHolder();

//    private Users users;
//
//    public SecurityContextHolder getSecurityContextHolder() {
//        return securityContextHolder;
//    }
//
//    public void setSecurityContextHolder(SecurityContextHolder securityContextHolder) {
//        this.securityContextHolder = securityContextHolder;
//    }
//
//    public Users getUsers() {
//        this.users = (Users) this.securityContextHolder.getContext().getAuthentication().getPrincipal();
//        return users;
//    }

//    public void setUsers(Users users) {
//        this.users = users;
//    }

    /*该方法用于传入某实例对象以及对象方法名，通过反射调用该对象的某个get方法*/
    private T getProperty(T beanObj, String property) throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        //此处应该判断beanObj,property不为null
        PropertyDescriptor pd = new PropertyDescriptor(property, beanObj.getClass());
        Method getMethod = pd.getReadMethod();
        if (getMethod == null) {

        }
        return (T) getMethod.invoke(beanObj);
    }

    /*该方法用于传入某实例对象以及对象方法名、修改值，通过放射调用该对象的某个set方法设置修改值*/
    private T setProperty(T beanObj, String property, Object value) throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        //此处应该判断beanObj,property不为null
        PropertyDescriptor pd = new PropertyDescriptor(property, beanObj.getClass());
        Method setMethod = pd.getWriteMethod();
        if (setMethod == null) {

        }
        return (T) setMethod.invoke(beanObj, value);
    }

    protected int add(T t) throws IllegalAccessException, IntrospectionException, InvocationTargetException {

//        setProperty(t, "crenteUserId", getUsers().getId());
        setProperty(t, "crenteUserId", 1L);
//        setProperty(t, "crenteUserName", getUsers().getUserName());
        setProperty(t, "crenteUserName", "admin");
        setProperty(t, "crenteDateTime", new Date());
//        setProperty(t, "lastUpdateUserId", getUsers().getId());
        setProperty(t, "lastUpdateUserId", 1L);
//        setProperty(t, "lastUpdateUserName", getUsers().getUserName());
        setProperty(t, "lastUpdateUserName", "admin");
        setProperty(t, "lastUpdateDateTime", new Date());

        T u = getMapper().save(t);
        System.out.println(u);
        if (u != null) {
            return SUCCESS;
        }

        return ERROR;


    }

    protected int update(T t) throws IllegalAccessException, IntrospectionException, InvocationTargetException {
//        setProperty(t, "lastUpdateUserId", getUsers().getId());
        setProperty(t, "lastUpdateUserId", 1L);
//        setProperty(t, "lastUpdateUserName", getUsers().getUserName());
        setProperty(t, "lastUpdateUserName", "admin");
        setProperty(t, "lastUpdateDateTime", new Date());
        if (getMapper().save(t) != null) {
            return SUCCESS;
        }
        return ERROR;
    }


    @Transient
    protected int deleteById(String idList) {
        String[] strs = idList.split(",");
        for(String str : strs){
            Long id = Long.parseLong(str);
            getMapper().deleteById(id);
        }

        return SUCCESS;
    }


    @Transient
    protected int logicDelete(String idList) throws IllegalAccessException, IntrospectionException, InvocationTargetException {

        String[] strs = idList.split(",");
        for(String str : strs){
            Long id = Long.parseLong(str);
            T t = getMapper().getById(id);
            setProperty(t, "isDelete", 1);
            int result = this.update(t);
        }
        return SUCCESS;
    }


    protected T getById(ID id) throws IllegalAccessException, IntrospectionException, InvocationTargetException {
        T t = (T) getMapper().findById(id);
        if(t == null){
            return null;
        }
        return t;
    }


    protected List<T> getAll() {
        return getMapper().findAll();
    }

    protected List<T> getAll(Specification specification){
        return getMapper().findAll(specification);
    }

    protected Page<T> getPage(Pageable pageable){
        return getMapper().findAll(pageable);
    }

    protected Page<T> getPage(Specification specification, Pageable pageable){
        return getMapper().findAll(specification,pageable);
    }




}
